using LightCAD.MathLib;
using System;
using System.Collections;
using System.Collections.Generic;
using static LightCAD.MathLib.Constants;

namespace LightCAD.Three
{
    public static  class UniformsUtils
    {
        public static Uniforms cloneUniforms(Uniforms src)
        {
            var dst = new Uniforms();
            foreach (var item in src)
            {
                var u = item.Key;
                dst[u] = new Uniform();
                var srcUniform = item.Value;
                var dstUniform = dst[u];
                foreach (var fItem in Uniform.fields)
                {
                    var propDef = fItem.Value;
                    var property = propDef.GetValue(srcUniform);

                    if (property != null && (property is Color ||
                        property is Matrix3 || property is Matrix4 ||
                        property is Vector2 || property is Vector3 || property is Vector4 ||
                        property is Texture || property is Quaternion))
                    {
                        if ((property as Texture)?.isRenderTargetTexture??false)
                        {
                            console.warn("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().");
                            propDef.SetValue(dstUniform, null);
                        }
                        else
                        {
                            propDef.SetValue(dstUniform, property.InvokeMethod("Clone"));
                        }
                    }
                    else if (property is Array)
                    {
                        propDef.SetValue(dstUniform, (property as Array).Clone());
                    }
                    else
                    {
                        propDef.SetValue(dstUniform, property);
                    }
                }
                
            }
            return dst;
        }
        public static Uniforms mergeUniforms(params Uniforms[] uniforms)
        {
            var merged = new Uniforms();
            for (var u = 0; u < uniforms.Length; u++)
            {
                var tmp = cloneUniforms(uniforms[u]);
                foreach (var item in tmp)
                {
                    var p = item.Key;
                    merged[p] = tmp[p];
                }
            }
            return merged;
        }
        public static ListEx<UniformsGroup> cloneUniformsGroups(ListEx<UniformsGroup> src)
        {
            if (src == null)
                return null;
            var dst = new ListEx<UniformsGroup>();
            for (var u = 0; u < src.Length; u++)
            {
                dst.Push(src[u].clone());
            }
            return dst;
        }
        public static ColorSpace getUnlitUniformColorSpace(WebGLRenderer renderer) 
        {
            if (renderer.getRenderTarget() == null)
            {

                // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398
                return renderer.outputEncoding == sRGBEncoding ? ColorSpace.SRGB : ColorSpace.LinearSRGB;

            }
            return ColorSpace.LinearSRGB;
        }
    }
}
